<script lang="ts">
	import { AObject } from "$lib/AObject";
	import { AZone } from "$lib/AZone";
	import { Agent } from "$lib/Agent";
	import { parseNumber } from "$lib/CommandParser";
	import { N, Pronoun, SP, Sentence, SyntaxPattern, type SyntaxElement, Signifier } from "$lib/NarrativeBase";
	import { Narrative } from "$lib/NarrativeContext";
	import { AAttributes, AClasses } from "$lib/Primitives";

	let expr = '';
    let time = 0;
    function take(sub: AObject | Agent, obj: AObject | Agent) {
        let s = new Sentence('action', 
            [N.S(sub), N.P(N.V('拿起'), N.O(obj))]);
        s.group = 'taking';
        s.startTime = time;
        time += 12;
        return s;
    }

    function eat(sub: AObject | Agent, obj: AObject | Agent) {
        let s = new Sentence('action', 
            [N.S(sub), N.P(N.V('吃了'), N.O(obj))]);
        s.group = 'eating';
        s.startTime = time;
        s.duration = 40;
        time += 50;
        return s;
    }

    function touch(sub: AObject | Agent, obj: AObject | Agent) {
        let s = new Sentence('action', 
            [N.S(sub), N.P(N.V('摸了摸'), N.O(obj))]);
        s.group = 'touching';
        s.startTime = time;
        time += 16;
        return s;
    }

    function thought(experiencer: AObject | Agent, sent: SyntaxElement[]) {
        let s = new Sentence('thought', sent);
        s.experiencer = [experiencer];
        s.startTime = time;
        time += 1;
        return s;
    }

    function testSyntaxPattern() {
        let A = new AObject('A', []);
        let s = N.SVO(A, '打开着');
        // let pat = [SP.or('', SP.signifier('sig'), SP.LIST('list'))];
        const pat = [
            SP.S('subj'), 
            SP.P('pred').with(SP.any().asterisk(), SP.V('v'), SP.any().asterisk())];
        let ret = SyntaxPattern.match(pat, s);
        console.log(ret);
    }

    function testParseNarrative() {
        let nowhere = new AZone('无地', []);
        let you = new Agent('你', Pronoun.You, nowhere);
        let B = new AObject('B', []);
        let X = new AObject('乒乓球', [], {}, [AAttributes.White], AClasses.PingpongBall);
        let A = new AObject('A', []);
        let Y = new AObject('绿粉笔', [], {}, [AAttributes.Green], AClasses.Chalk);
        let Z = new AObject('黄香蕉', [], {}, [AAttributes.Yellow], AClasses.Banana);

        let RApples: AObject[] = [];
        for (let i = 0; i < 5; i++)
            RApples.push(new AObject(
                '红苹果', [], {}, [AAttributes.Red], AClasses.Apple));
        RApples.forEach((x) => x.prototype = RApples[0]);
        let GApples: AObject[] = [];
        for (let i = 0; i < 5; i++)
            GApples.push(new AObject(
                '绿苹果', [], {}, [AAttributes.Green], AClasses.Apple));
        GApples.forEach((x) => x.prototype = GApples[0]);

        let fragment = [
            touch(A, X), touch(B, X), touch(A, Y), touch(A, Z), 
            take(you, RApples[0]), take(you, GApples[0]), take(you, RApples[1]),
            take(you, RApples[2]), take(you, Z), take(you, Y), eat(you, Z),
            take(you, GApples[1]), take(you, Y), 
            touch(you, Y),
            thought(you, [N.S(Y), N.P(N.V('看起来很好吃'))]),
            eat(you, Y), eat(you, RApples[1]),
            touch(B, A), touch(B, Z),
        ];
        
        let narr = new Narrative();
        narr.context.cache[Pronoun.You] = you;
        narr.context.freeIndirectSubject.add(you);
        console.log(narr.debugPrint(fragment));
        fragment = narr.optimize(fragment);
        narr.updatePronouns(fragment);
        console.log(narr.debugPrint(fragment));
        fragment.forEach((x) => console.log(narr.confabulate(x)));
    }
</script>

<input bind:value={expr} placeholder="enter expression" style="width: 500px;" />
<p>{parseNumber(expr)}</p>
<p>{testParseNarrative()}</p>
